package com.example.android.utils

import android.util.Log
import kotlinx.coroutines.*
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.IOException
import kotlin.coroutines.suspendCoroutine

/**
 * @ClassName Api
 * @Author Ryan Kamanri
 * @Date 2022/6/1
 * @Description 统一HTTP接口服务封装
 **/
class Api(host : String) {
    val JSON_ENCTYPE = "application/json;charset=utf-8"
    val Host : String = host
    private val httpClient : OkHttpClient = OkHttpClient()

    private var _Preset: (builder: Request.Builder) -> Unit = { }

    fun SetPreset(presetHeader: (builder: Request.Builder) -> Unit): Api {
        _Preset = presetHeader
        return this
    }

    suspend fun Get(uri: String, setRequestHandler: (Request.Builder) -> Unit = { }): Response {
        return withContext(Dispatchers.IO){
            val builder = Request.Builder()
                .url("${Host}${uri}")
                .get()
            _Preset(builder)
            setRequestHandler(builder)

            try {
                httpClient.newCall(builder.build()).execute()
            }catch (e: Exception) {
                Log.e(toString(),"An Exception Occured While Execute The HTTP Request \n Caused By : $e : ${e.message}")
                e.printStackTrace()
                throw e
            }

        }

    }

    suspend fun Post(uri: String, setRequestBodyHandler : (FormBody.Builder) -> Unit, setRequestHandler: (Request.Builder) -> Unit = { }): Response {

        return withContext(Dispatchers.IO) {

            val requestBody = FormBody.Builder()
            setRequestBodyHandler(requestBody)

            val builder = Request.Builder()
                .url("${Host}${uri}")
                .post(requestBody.build())
            _Preset(builder)
            setRequestHandler(builder)


            try {
                httpClient.newCall(builder.build()).execute()
            }catch (e: Exception) {
                Log.e(toString(),"An Exception Occured While Execute The HTTP Request \n Caused By : $e : ${e.message}")
                e.printStackTrace()
                throw e
            }
        }
    }

    suspend fun Post(uri: String, json: String, setRequestHandler: (Request.Builder) -> Unit = { }): Response {

        return withContext(Dispatchers.IO) {

            val requestBody = json.toRequestBody(JSON_ENCTYPE.toMediaType())

            val builder = Request.Builder()
                .url("${Host}${uri}")
                .post(requestBody)
            _Preset(builder)
            setRequestHandler(builder)

            try {
                httpClient.newCall(builder.build()).execute()
            }catch (e: Exception) {
                Log.e(toString(),"An Exception Occured While Execute The HTTP Request \n Caused By : $e : ${e.message}")
                e.printStackTrace()
                throw e
            }
        }
    }
}